package com.zmn.mcc.cas.server.boot.autoconfigure;

import com.zmn.mcc.cas.core.MccCookie;
import com.zmn.mcc.cas.core.ZmnSessionFactory;
import com.zmn.mcc.cas.server.ZmnStaffActiveHandler;
import com.zmn.mcc.cas.server.shiro.ZmnWebSessionManager;
import com.zmn.mcc.cas.web.dao.RedisSessionDao;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * @uthor nowind
 * @since 2018/09/10 15:48
 */
@Configuration
@EnableConfigurationProperties(CasServerProperties.class)
class CasServerShiroConfiguration {

    // 否允许账号多处登录
//    @Value("${shiro.account.share}")
//    private Boolean accountShare = false;

    @Autowired
    private CasServerProperties casServerProperties;

    /**
     * 会话DAO(自定义)
     * 使用redis持久化
     */
    @Bean
    public RedisSessionDao redisSessionDao(JavaUuidSessionIdGenerator sessionIdGenerator) {
        RedisSessionDao redisSessionDao = new RedisSessionDao();
        redisSessionDao.setSessionIdGenerator(sessionIdGenerator);
        return redisSessionDao;
    }


    /**
     * 缓存管理器,使用Ehcache实现
     */
    @Bean
    public EhCacheManager shiroEhCacheManager() {
        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile(casServerProperties.getEhcachePath());
        return cacheManager;
    }

    /**
     * 会话ID生成器
     */
    @Bean
    public JavaUuidSessionIdGenerator sessionIdGenerator() {
        return new JavaUuidSessionIdGenerator();
    }

    /**
     * 会话Cookie模板
     */
    @Bean
    public MccCookie sessionIdCookie() {
        MccCookie mccCookie = new MccCookie();
        mccCookie.setName(casServerProperties.getCookieName());       // cookie的name
        mccCookie.setDomain(casServerProperties.getCookieDomain());   // cookie存储的domain
        mccCookie.setMaxAge(casServerProperties.getCookieMaxAge());   // cookie的有效时间(秒),-1表示浏览器关闭时失效
        mccCookie.setPath(casServerProperties.getCookiePath());       // cookie存储的path
        mccCookie.setHttpOnly(Boolean.TRUE);
        return mccCookie;
    }

    /**
     * 会话验证调度器
     */
//    @Bean
//    public ExecutorServiceSessionValidationScheduler sessionValidationScheduler(ValidatingSessionManager sessionManager) throws Exception {
//        ExecutorServiceSessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
//        sessionValidationScheduler.setInterval(sessionValidationInterval);  // 调度时间间隔(单位毫秒)
//        sessionValidationScheduler.setSessionManager(sessionManager);       // 会话验证调度器进行会话验证时的会话管理器
//        return sessionValidationScheduler;
//    }

    /**
     * 会话管理器
     * 自己维护会话，废弃了Servlet容器的会话管理
     */
    @Bean
    public DefaultWebSessionManager sessionManager(MccCookie sessionIdCookie,
                                                   RedisSessionDao redisSessionDao) {
        ZmnWebSessionManager sessionManager = new ZmnWebSessionManager();
        sessionManager.setGlobalSessionTimeout(casServerProperties.getSessionTimeout());                     // 全局会话超时时间(单位毫秒)
        sessionManager.setDeleteInvalidSessions(true);                              // 是否删除过期会话,默认开启
        //sessionManager.setSessionValidationSchedulerEnabled(true);                  // 是否开启会话验证调度器，默认开启
        //sessionManager.setSessionValidationScheduler(sessionValidationScheduler); // 会话验证调度器，默认使用ExecutorServiceSessionValidationScheduler
        //sessionManager.setSessionValidationInterval(sessionValidationInterval);   // 相隔多久检查一次session的有效性(单位毫秒)
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdCookie(sessionIdCookie);
        sessionManager.setSessionDAO(redisSessionDao);
        sessionManager.setSessionFactory(new ZmnSessionFactory());

        return sessionManager;
    }

    @Bean
    public ZmnStaffActiveHandler zmnAuthenticationListener(RedisTemplate redisTemplate) {
        ZmnStaffActiveHandler listener = new ZmnStaffActiveHandler();
        listener.setRedisTemplate(redisTemplate);
        ZmnSessionFactory.addTouchListener(listener);
        return listener;
    }

}
